package org.stratusdb.funsql.execute;

import java.util.Vector;

import org.stratusdb.Config;
import org.stratusdb.error.Error;
import org.stratusdb.types.AbstractSimpleType;
import org.stratusdb.types.TableType;
import org.stratusdb.types.TupleType;

public class NestedLoopJoin extends BinaryOperator {

	private static final long serialVersionUID = 1584348658063938054L;
	private Vector<Integer> projAttr;
	private int leftAttr;
	private int rightAttr;
	public NestedLoopJoin(AbstractOperator leftChild,
			AbstractOperator rightChild, int leftAttr, int rightAttr, Vector<Integer> projAttr) {
		super(leftChild, rightChild);
		this.leftAttr = leftAttr;
		this.rightAttr = rightAttr;
		this.projAttr = projAttr;
	}

	@Override
	public Error open() {
		this.leftChild.open();
		/*this.rightChild.open();
		this.flag = rightChild;*/
		return Error.NO_ERROR;
	}

	@Override
	public TableType next() {
		int b = 0;
		TableType rettab = null;
		TableType tt;
		//return this.leftChild.next();+
		while(( tt = this.leftChild.next())!=null){
			rettab = new TableType(Config.EXECUTE_MAX_FETCHSIZE);
			for(TupleType tutyl : tt.getTuples())
			{
				if(tutyl == null) break;
				rightChild.open();
				TableType taty;
				while((taty = this.rightChild.next()) != null)
				{
					for(TupleType tutyr : taty.getTuples())
					{
						if(tutyr == null) break;
						int c = 0;
						TupleType r = new TupleType(tutyl.size()+tutyr.size());
						if(tutyr.getValue(leftAttr).equals(tutyl.getValue(rightAttr))) {
							for(AbstractSimpleType at : tutyl.getValues())
							{
								r.setValue(c++, at);
							}
							for(AbstractSimpleType at : tutyr.getValues())
							{
								r.setValue(c++, at);
							}
							rettab.setTuple(b++, r);
						}
						
					}
				}
				rightChild.close();
			}
		}
		System.out.println(rettab.size());
		return rettab;
	}

	@Override
	public Error close() {
		this.leftChild.close();
		return Error.NO_ERROR;
	}

	@Override
	public String toString() {
		StringBuffer sb = new StringBuffer("NestedLoopJoin : Selectionsattribute : ");
		sb.append(this.leftAttr + " = " + this.rightAttr);
		sb.append(" : Projectionsattribute : ");
		for(Integer i : this.projAttr) {
			sb.append(i + " ");
		}
		return sb.toString();
	}

}
